package com.lcf.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.lcf.framework.utils.UserUtils;
import com.lcf.framework.vo.PageVO;
import com.lcf.system.dao.MovieBuyDao;
import com.lcf.system.entity.Movie;
import com.lcf.system.entity.MovieBuy;
import com.lcf.system.entity.MovieType;
import com.lcf.system.query.MovieBuyPageQuery;
import com.lcf.system.service.MovieBuyService;
import com.lcf.system.vo.MovieBuyVO;
import com.lcf.system.vo.MovieTypeVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 购买(MovieBuy)表服务实现类
 *
 * @author lcf
 * @since 2025-05-07 22:23:22
 */
@Service("movieBuyService")
public class MovieBuyServiceImpl extends ServiceImpl<MovieBuyDao, MovieBuy> implements MovieBuyService {

    @Override
    public PageVO<MovieBuyVO> page(MovieBuyPageQuery query) {
        Page<MovieBuy> page = Db.lambdaQuery(MovieBuy.class)
                .eq(query.getUserId() != null, MovieBuy::getUserId, query.getUserId())
                .eq(query.getMovieId() != null, MovieBuy::getMovieId, query.getMovieId())
                .orderByDesc(MovieBuy::getCreateTime)
                .page(query.toPage());

        if (page != null && page.getRecords() != null && !page.getRecords().isEmpty()) {
            PageVO<MovieBuyVO> result = new PageVO<>(page, MovieBuyVO.class);

            List<Long> movieIdList = result.getList().stream().map(MovieBuyVO::getMovieId).distinct().toList();
            List<MovieType> movieTypes = Db.lambdaQuery(MovieType.class).in(MovieType::getMovieId, movieIdList).list();
            Map<Long, List<MovieTypeVO>> map = movieTypes.stream().map(x -> BeanUtil.copyProperties(x, MovieTypeVO.class))
                    .collect(Collectors.groupingBy(MovieTypeVO::getMovieId));

            result.getList().forEach(x -> x.setMovieTypes(map.get(x.getMovieId())));

            return result;
        }

        return new PageVO<>(page, MovieBuyVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void buy(long movieId) {
        if (Db.lambdaQuery(MovieBuy.class).eq(MovieBuy::getMovieId, movieId).eq(MovieBuy::getUserId, UserUtils.getUserId()).exists()) {
            throw new RuntimeException("您已购买过此电影!");
        }

        new MovieBuy(UserUtils.getUserId(), movieId).insert();

        Db.lambdaQuery(Movie.class).eq(Movie::getId, movieId).oneOpt().ifPresent(x -> {
            x.setBuyTimes(x.getBuyTimes() + 1);
            x.updateById();
        });
    }
}

